package com.elong.qadev.self;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.elong.qadev.entity.Entities;
import com.elong.qadev.entity.Header;
import com.elong.qadev.entity.HttpCase;
import com.elong.qadev.entity.NameValuePair;
import com.elong.qadev.entity.RunAfter;
import com.elong.qadev.entity.RunBefore;
import com.elong.qadev.entity.UrlParam;
import com.elong.qadev.run.RunClient;
import com.elong.qadev.service.HttpCaseServiceI;
import com.elong.qadev.tool.DBUtils;
import com.elong.qadev.tool.LoggerUtils;
/**
 * 
* @ClassName: BeforeMethod
* @Description: TODO(前置条件方法存放类)
* @author kangchen
* @date 2015年10月2日
*
 */
public class BeforeMethod extends MethodTypeConstant{
	Logger logger = Logger.getLogger(BeforeMethod.class);
	public Map<String, String> content;
	public boolean isExpected;
	public String strLog = "";

	public String getStrLog() {
		return strLog;
	}

	public void setStrLog(String strLog) {
		this.strLog = strLog;
	}

	public HttpCaseServiceI httpCaseService;

	public boolean isExpected() {
		return isExpected;
	}

	public void setExpected(boolean isExpected) {
		this.isExpected = isExpected;
	}

	public Map<String, String> getContent() {
		return content;
	}

	public void setContent(Map<String, String> content) {
		this.content = content;
	}

	@RunCase(type=RUN_CASE,description = "根据输入的[id]值，根据[value]值s指定运行下一个测试用例的时间间隔")
	public void runCaseByTimes(String id, String value) throws Exception {
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				new String[] { "spring.xml", "spring-hibernate.xml" });
		httpCaseService = (HttpCaseServiceI) ac.getBean("httpCaseService");
		int caseId = Integer.parseInt(id.split("-")[1]);
		ArrayList<Header> lh = new ArrayList<Header>();
		lh = httpCaseService.getHeaders(caseId);
		ArrayList<UrlParam> lu = new ArrayList<UrlParam>();
		lu = httpCaseService.getUrlParams(caseId);
		ArrayList<NameValuePair> ln = new ArrayList<NameValuePair>();
		ln = httpCaseService.getNameValuePairs(caseId);
		ArrayList<RunBefore> lb = new ArrayList<RunBefore>();
		lb = httpCaseService.getRunBefores(caseId);
		ArrayList<RunAfter> lr = new ArrayList<RunAfter>();
		lr = httpCaseService.getRunAfters(caseId);
		HttpCase httpCase = new HttpCase();
		httpCase = httpCaseService.getHttpCase(caseId);
		Entities entities = new Entities();
		entities = httpCaseService.getEntities(caseId);
		Map<String, Object> content = new HashMap<String, Object>();
		content.put("httpCase", httpCase);
		content.put("entities", entities);
		content.put("headers", lh);
		content.put("urlParams", lu);
		content.put("nameValuePairs", ln);
		content.put("runBefores", lb);
		content.put("runAfters", lr);

		logger.debug("***********************************************************");
		strLog += LoggerUtils.log("**************************开始执行前置用例（" + id
				+ "）*****************************");
		RunClient rc = new RunClient(content);
		rc.run();
		strLog += rc.getStrLog();
		strLog += LoggerUtils.log("**************************前置用例（" + id
				+ "）执行完毕***************************");
		Map<String, String> newContent = rc.getContent();
		logger.debug("****新注入content**************************************************************");
		for (String key : newContent.keySet()) {
			logger.debug("key:" + key);
			logger.debug("value:" + newContent.get(key));
		}
		logger.debug("****原有content**************************************************************");
		for (String key : this.content.keySet()) {
			logger.debug("key:" + key);
			logger.debug("value:" + this.content.get(key));
		}
		boolean isExist = true;
		for (String key : newContent.keySet()) {
			for (String keyOld : this.content.keySet()) {
				if (key.equals(keyOld)) {
					isExist = false;
				}
			}
			if (isExist) {
				this.content.put(key, newContent.get(key));
			}
		}
		logger.debug("****融合content**************************************************************");
		for (String key : this.content.keySet()) {
			logger.debug("key:" + key);
			logger.debug("value:" + this.content.get(key));
		}

	}

	@ParamSave(type=PARAM_GEN,description = "添加/更新变量名为[name]的上下文环境，使得变量值为YYYY-MM-DD格式字符串，根据[value]值前后偏移当前日期")
	public void getymd(String name, String value) {
		Integer expectInt = Integer.valueOf(value.trim());
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.set(Calendar.DAY_OF_MONTH,
				(calendar.get(Calendar.DAY_OF_MONTH) + expectInt));
		value = (calendar.get(Calendar.YEAR)) + "-"
				+ (calendar.get(Calendar.MONTH) + 1) + "-"
				+ calendar.get((Calendar.DAY_OF_MONTH));
		try {
			logger.info(value);
		} catch (Exception e) {
			e.printStackTrace();
		}
		content.put(name, value);
	}

	@ParamSave(type=PARAM_GEN,description = "添加/更新变量名为[name]的上下文环境，使得变量值为YYYY-MM-DD hh:mm:ss格式字符串，根据[value]值前后偏移当前日期")
	public void getTime(String name, String value) {
		Integer expectInt = Integer.valueOf(value.trim());
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.set(Calendar.DAY_OF_MONTH,
				(calendar.get(Calendar.DAY_OF_MONTH) + expectInt));
		value = (calendar.get(Calendar.YEAR)) + "-"
				+ (calendar.get(Calendar.MONTH) + 1) + "-"
				+ calendar.get((Calendar.DAY_OF_MONTH)) + " "
				+ calendar.get(Calendar.HOUR_OF_DAY) + ":"
				+ calendar.get(Calendar.MINUTE) + ":"
				+ calendar.get(Calendar.SECOND);
		try {
			logger.info(value);
		} catch (Exception e) {
			e.printStackTrace();
		}
		content.put(name, value);
	}

	@ParamSave(type=PARAM_GEN,description = "添加/更新变量名为[name]的上下文环境，变量为随机组成的字符串，根据[value]值定义字符串长度")
	public void getString(String name, String value) {
		Integer expectInt = Integer.valueOf(value.trim());
		String base = "abcdefghijklmnopqrstuvwxyz0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < expectInt; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		value = sb.toString();
		try {
			logger.info(value);
		} catch (Exception e) {
			e.printStackTrace();
		}
		content.put(name, value);
	}

	@ParamSave(type=PARAM_SAVE,description = "添加/更新变量名为[name]的上下文环境，随机获取输入的字符串其中的一个，以分号分隔，根据[value]值随机获取示例[BJS;SHA;1231;ow;rt;ff]")
	public void getRandomInput(String name, String value) {
		String[] str = value.toString().split(";");
		Random random = new Random();
		int number = random.nextInt(str.length);
		System.out.println(number + "-" + str[number]);
		content.put(name, str[number]);
	}

	@ParamSave(type=PARAM_SAVE,description = "添加/更新名为[name]的上下文环境，使得值为[value]")
	public void addContext(String name, String value) {
		content.put(name, value);
	}

	@ParamSave(type=PARAM_DB,description = "添加/更新名为[name]的上下文环境，使得值为执行[sqlId]对应的SQL语句返回值")
	public void addContextFromSQL(String name, String sqlId) throws Exception {
		 List<String[]> results = DBUtils.querySQL(sqlId);
		 addContext(name, results.get(0)[0]);
	}

//	@ParamSave(description = "将[sqlId]对应的SQL语句返回值放到上下文环境中")
//	public void addContextsFromSQL(String sqlId) throws Exception {
//		Map<Integer, String> meta = new HashMap<Integer, String>();
//		List<String[]> results = DBUtils.querySQL(sqlId, meta);
//		for (Integer k : meta.keySet()) {
//			String name = meta.get(k);
//			StringBuilder sb = new StringBuilder();
//			for (int i = 0; i < results.size(); ++i) {
//				if (0 != i) {
//					sb.append(",");
//				}
//				sb.append(results.get(i)[k]);
//			}
//			addContext(name, sb.toString());
//		}
//	}

	@ParamSave(type=PARAM_DB,description = "执行[sqlId]对应的SQL语句")
	public void executeSQL(String sqlId) throws Exception {
		 DBUtils.updateDB(sqlId);
	}

	@ParamSave(type=PARAM_SAVE,description = "移除名为[name]的上下文环境")
	public void removeContext(String name) {
		content.remove(name);
	}

	@ParamSave(type=PARAM_SAVE,description = "清空上下文环境")
	public void clearContext() {
		content.clear();
	}
}
